using System;
using System.Collections;
using System.Text;
using System.Globalization;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using PIM.Utilities.Logging; 

namespace PIM.Utilities
{
    public class QSecureHelper
    {
        private static ArrayList standardPersonFields = new ArrayList();
        private static ArrayList standardClearanceFields = new ArrayList();
        [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool lpSystemInfo);  

        #region Constants
        public const string QSIDENTIFIER = "QSID";
        public const string QSIDCREATEDDATE = "QSCREATIONDATE";
        public const string QSIDMODIFIEDDATE = "QSMODIFIEDDATE";
        public const string QSIDUPDATECOUNT = "QSUPDATECOUNT";
        public const string SYSTEMID = "SystemID";
        public const int SAFE_SYSTEMID = 1;
        public const int POLICY_SYSTEMID = 0;
        public const int SELFSERVICE_SYSTEMID = 5;
        public const string PERSONZONES = "PersonZones";
        public const string MSSPERSONID = "MSSPERSONID";
        public const string PERSONID = "PERSONID";
        public const string CLEARID = "CLEARID";
        public const string MSSCLEARID = "MSSCLEARID";
        public const string CARDID = "CARDID";
        public const string MSSCARDID = "MSSCARDID";
        public const string CARD = "Card";
        public const string PERSONCLEARANCES = "PersonClearances";
        public const string VISITOR = "Visitor";
        public const string VISITORCARDS = "VISITORCARDS";
        public const string VISITORCLEARANCES = "VisitorClearances";
        public const string MEETING_CLEARANCES = "MeetingClearances";
        public const string DELETE = "Delete";
        public const string ADD = "Add";
        public const string MODIFY = "Modify";
        public const string PROFILEID = "PROFILEID";
        public const string ZONEID = "ZONEID";
        public const string EMPLOYERID = "EMPLOYERID";

        public const string REQUESTID = "REQUESTID";
        public const string REQUESTORID = "REQUESTORID";
        public const string REQUESTORTYPE = "REQUESTORTYPE";
        public const string REQUESTSTATUS = "REQUESTSTATUS";
        public const string REQUEST = "Request";
        public const string LEVEL = "LEVEL";
        public const string SAFE_POLICY_REASON = "SAFEPOLICYREASON";
        public const string REQUEST_TYPE = "REQUESTTYPE";
        public const string DEFAULT_REQUEST_TYPE = "Data Change";



        public const string MAILTEMPLATEID = "TEMPLATEID";
        public const string MAILCC = "CC";

        public const string TIMEZONE = "TIMEZONE";
        public const string TIMESCHEDULE = "TIMESCHEDULE";

        public const string ACTIVATIONDATE = "ACTIVATIONDATE";
        public const string DEACTIVATIONDATE = "DEACTIVATIONDATE";

        public readonly static char[] COMMA = { ',' };

        public const string EQ_CONDITION = "{0} = {1}";
        public const string IN_CONDITION = "{0} IN ({1})";
        public const string SINGLEQUOTE_FORMAT = "'{0}'";

        public const string LAST_ASSIGNED_PROFILES = "LASTASSIGNEDPROFILES";
        public const string ACCESS_PROFILE = "PersonAccessProfile";
        public const string PERSON = "Person";

        public const string ALL = "All";
        public const string QSOPSTATUS = "QSOPSTATUS";

        public const string APPLIES_WHEN = "AppliesWhen";
        public const string TYPE = "TYPE";

        public const string HEADER = "Header";
        public const string INDEX = "Index";
        public const string NULL = "NULL";
        public const string TRUE = "true";
        public const string FALSE = "false";

        public const string MODIFIED_SYSTEMID = "ModifiedSystemID";
        public const string MODIFIED_DATE = "ModifiedDate";
        public const string CREATION_SYSTEMID = "CreationSystemID";
        public const string MESSAGEID = "MessageID";
        public const string CREATION_DATE = "CreationDate";
        public const string OPERATION = "Operation";

        public const string INBOUND_DATASTORE = "InboundDataStore";
        public const string OUTBOUND_DATASTORE = "OutboundDataStore";

        public const string SYSTEMSPECIFIC = "CardsAreSpecificToSystem";

        public const string HEARTBEAT = "Heartbeat";
        public const string HEART_BEAT_INTERVAL = "HeartbeatInterval";
        public const string BIZTALKOUTPUTQUEUE = "BizTalkOutputQueue";
        public const string RULE_ENGINE_QUEUE = "saferule";
        public const string LOCALHOST = "localhost";

        public const string SAFEDB = "SAFEKIOSKDB";
        public const string LAST_IMPORTED_DATETIME = "LastImportedDateTime";

        #endregion Constants

        static QSecureHelper()
        {
            standardPersonFields.Add("PhysObjectID");
            standardPersonFields.Add("FirstName");
            standardPersonFields.Add("MiddleName");
            standardPersonFields.Add("LastName");
            standardPersonFields.Add("AddressLine1");
            standardPersonFields.Add("AddressLine2");
            standardPersonFields.Add("City");
            standardPersonFields.Add("State");
            standardPersonFields.Add("Country");
            standardPersonFields.Add("Zip");
            standardPersonFields.Add("Phone1");
            standardPersonFields.Add("Phone2");
            standardPersonFields.Add("Phone3");
            standardPersonFields.Add("Status");
            standardPersonFields.Add("Email");
            standardPersonFields.Add("ManagerEmail");
            standardPersonFields.Add("UserName");
            standardPersonFields.Add("ManagerID");
            standardPersonFields.Add("Picture");
            standardPersonFields.Add("Signature");
            standardPersonFields.Add("Fingerprint");

            standardClearanceFields.Add("MSSPersonID");
            standardClearanceFields.Add("MSSClear_ID");
            standardClearanceFields.Add("SystemID");
            standardClearanceFields.Add("BadgeID");
            standardClearanceFields.Add("BadgeType");
            standardClearanceFields.Add("Type");
            standardClearanceFields.Add("ActivationDt");
            standardClearanceFields.Add("DeactivationDt");
            standardClearanceFields.Add("Priority");
            standardClearanceFields.Add("Grant");

        }

        public static bool Is64Bit()
        {
            bool retVal;
            try
            {
                IsWow64Process(System.Diagnostics.Process.GetCurrentProcess().Handle, out retVal);
            }
            catch (Exception ex)
            {
                //GlobalLog.Logger.LogError(ex.ToString());
                retVal = false; 
            }
            return retVal;
        } 

        public static ArrayList StandardPersonFieldNames
        {
            get { return standardPersonFields; }
        }

        public static ArrayList StandardClearanceFieldNames
        {
            get { return standardClearanceFields; }
        }

        public static bool ConvertToBool(object input)
        {
            bool result = false;
            if (input != null && input != DBNull.Value)
            {
                string val = input.ToString().Trim();
                //Non-zero value is true
                //"true" is true
                if (string.Compare(val, "false", true) == 0 || val == "0" || val == "")
                {
                    result = false;
                }
                else
                    result = true;
            }
            return (result);
        }

        public static string Replace(string input, string oldvalue, string newvalue)
        {
            //string result = "";
            //result = Regex.Replace(input, oldvalue, newvalue, RegexOptions.IgnoreCase);

            if (input == null || oldvalue == null || newvalue == null)
            {
                return (input);
            }

            if (input == string.Empty || oldvalue == string.Empty)
            {
                return (input);
            }

            StringBuilder result = new StringBuilder(input);
            string inputLower = input.ToLower();
            string oldvalueLower = oldvalue.ToLower();
            int index = 0;
            int tgtIndex = 0;

            while ((tgtIndex = inputLower.IndexOf(oldvalueLower, index)) != -1)
            {
                result.Remove(tgtIndex, oldvalueLower.Length);
                result.Insert(tgtIndex, newvalue);
                index = tgtIndex + oldvalueLower.Length;
            }

            return (result.ToString());
        }

        public static DateTime ConvertStringToDateTime(string sdate, bool bThrowException)
        {
            try
            {
                string[] expectedFormats = { "G", "g", "D", "d", "F", "f", "M/dd/yyyy hh:mm:ss tt"};
                IFormatProvider culture = new CultureInfo("en-US", true);
                DateTime dt = DateTime.ParseExact(sdate,
                    expectedFormats, culture,
                    DateTimeStyles.AllowWhiteSpaces);
                return dt;
            }
            catch (Exception ex)
            {
                GlobalLog.Logger.LogError("Input value = {0}; Exception = {1}", sdate == null ? "NULL" : sdate, ex.ToString());
                if (bThrowException)
                    throw;
                return DateTime.MinValue;
            }
        }

        public const string CONTROL_CHARS = @"[\x00-\x1F\x7F]";
        public static string PrepareFieldValue(object input, bool doTrim, bool doControlCharReplace, bool isDateField)
        {
            string result = string.Empty;

            if (input == null || input.ToString() == string.Empty)
            {
                return result;
            }

            if (doTrim)
            {
                result = input.ToString().Trim();
            }
            else
            {
                result = input.ToString();
            }

            if (doControlCharReplace)
            {
                result = System.Text.RegularExpressions.Regex.Replace(result, CONTROL_CHARS, string.Empty);
            }

            if (isDateField)
            {
                try
                {
                    DateTime dtTime = QSecureHelper.ConvertStringToDateTime(result);
                    if (dtTime.Year == 1900)
                    {
                        result = string.Empty;
                    }
                }
                catch (Exception ex)
                {
                    result = string.Empty;
                }
            }

            return (result);
        }


        public static DateTime ConvertStringToDateTime(string sdate)
        {
            return ConvertStringToDateTime(sdate, true); //always throw exception
        }

        public static string ConvertDateTimeToString(DateTime dt)
        {
            return dt.ToString("G");
        }

        public static string GetCurrentDateTime()
        {
            return ConvertDateTimeToString(System.DateTime.Now);
        }

        public static string GetOperationString(string operationNum)
        {
            OPERATIONTYPE opType = (OPERATIONTYPE)Convert.ToInt32(operationNum);
            if (Enum.IsDefined(typeof(OPERATIONTYPE), opType))
                return Enum.GetName(typeof(OPERATIONTYPE), opType);
            else
                return "";
        }

        public static string GetOperationNumber(string operationString)
        {
            try
            {
                OPERATIONTYPE opType = (OPERATIONTYPE)Enum.Parse(typeof(OPERATIONTYPE), operationString, true);
                return ((int)opType).ToString();
            }
            catch
            {
                return "";
            }
        }

        public static int ConvertSecondsToMilliseconds(string val)
        {
            return Convert.ToInt32(TimeSpan.FromSeconds(Convert.ToInt32(val)).TotalMilliseconds);
        }

        public static int ConvertMinutesToSeconds(string val)
        {
            return Convert.ToInt32(TimeSpan.FromMinutes(Convert.ToDouble(val)).TotalSeconds);
        }
        public static double ConvertSecondsToMinutes(string val)
        {
            return Convert.ToDouble(TimeSpan.FromSeconds(Convert.ToDouble(val)).TotalMinutes);
        }

        public static bool IsLocalMachine(string machineName)
        {
            if (machineName != null)
                machineName = machineName.Trim();

            if (machineName == null || machineName.Length == 0 ||
                string.Compare(machineName, "localhost", true) == 0 ||
                string.Compare(machineName, "local", true) == 0 ||
                string.Compare(machineName, ".", true) == 0 ||
                string.Compare(machineName, System.Environment.MachineName, true) == 0)
                return true;
            else
                return false;
        }

        public static bool IsEmpty(object o)
        {
            if (o != null && o.ToString().Length != 0)
                return false;
            else
                return true;
        }

        public static string EscapeSQL(string input)
        {
            return input.Replace("'", "''");
        }

        public static string CreateString<T>(ICollection<T> collection, string separationToken,
            bool removeDuplicates)
        {
            StringBuilder buffer = new StringBuilder();
            List<T> list = new List<T>();
            foreach (T t in collection)
            {
                if (removeDuplicates && list.Contains(t))
                {
                    continue;
                }
                list.Add(t);
                if (buffer.Length != 0)
                    buffer.Append(separationToken);
                buffer.Append(t.ToString());
            }
            return buffer.ToString();
        }

        public static string CreateCommaSeparatedString<T>(ICollection<T> collection, bool removeDuplicates)
        {
            return CreateString(collection, ",", removeDuplicates);
        }

        public static string CreateCommaSeparatedString<T>(ICollection<T> collection)
        {
            StringBuilder buffer = new StringBuilder();
            foreach (T t in collection)
            {
                if (buffer.Length != 0)
                    buffer.Append(",");
                buffer.Append(t.ToString());
            }
            return buffer.ToString();
        }

        public static string CreateCommaSeparatedQuotedString<T>(ICollection<T> collection, string quoteChar)
        {
            StringBuilder buffer = new StringBuilder();
            foreach (T t in collection)
            {
                if (buffer.Length != 0)
                    buffer.Append(",");
                buffer.AppendFormat("{0}{1}{0}", quoteChar, EscapeSQL(t.ToString()));
            }
            return buffer.ToString();
        }

        public static string[] SplitCommaSeparatedString(string input)
        {
            return SplitCommaSeparatedString(input, true);
        }

        public static string[] SplitCommaSeparatedString(string input, bool removeEmpty)
        {
            return input.Split(COMMA, removeEmpty ? StringSplitOptions.RemoveEmptyEntries :
                StringSplitOptions.None);
        }

        public static string[] SplitString(string input, string separationToken, bool removeEmpty)
        {
            string[] separationTokens = new string[1];
            separationTokens[0] = separationToken;
            return input.Split(separationTokens, removeEmpty ? StringSplitOptions.RemoveEmptyEntries :
                StringSplitOptions.None);
        }

    }


}
